/**
 * QueryUtils.java
 * created by wesley at 2008-6-7
 */
package net.sf.filelink.utl;

import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;

import net.sf.filelink.FileLinkPlugin;
import net.sf.filelink.preferences.PreferenceConstants;

import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceProxy;
import org.eclipse.core.resources.IResourceProxyVisitor;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.dialogs.FilteredResourcesSelectionDialog;
import org.eclipse.ui.ide.IDE;

/**
 * QueryUtils
 * 
 * @author wesley
 */
public class QueryUtils {

    /**
     * Search the file resources by the given filePath
     * 
     * @return the resources which match the given filePath
     */
    public static List<IFile> findFileResources(final String filePath, IContainer... searchFolders) {

        final List<IFile> results = new ArrayList<IFile>();

        IResourceProxyVisitor visitor = new IResourceProxyVisitor() {

            protected boolean isMatch(IFile file) {
                String path = file.getProjectRelativePath().toString();
                if (path != null && path.indexOf(filePath) != -1) {
                    return true;
                }
                return false;
            }

            public boolean visit(IResourceProxy proxy) {
                if (proxy.getType() == IResource.FILE) {
                    IFile file = (IFile) proxy.requestResource();
                    if (isMatch(file)) {
                        results.add(file);
                    }
                }
                return true;
            }
        };

        List<IResource> containers = new ArrayList<IResource>();

        if (searchFolders != null) {
            for (int i = 0; i < searchFolders.length; i++) {
                containers.add(searchFolders[i]);
            }
        }

        if (containers == null || containers.isEmpty()) {
            containers.add(ResourcesPlugin.getWorkspace().getRoot());
        }

        for (IResource container : containers) {
            try {
                container.accept(visitor, IResource.DEPTH_INFINITE);
            } catch (CoreException e) {
                // ignore this exception
                e.printStackTrace();
            }
        }

        return results;
    }

    /**
     * Use FilteredResourcesSelectionDialog to open resources;
     * 
     * @param filePathPattern
     */
    public static void openFileResources(String searchPattern) {

        // convert to file path pattern
        String filePathPattern = QueryUtils.toFileName(searchPattern);

        // Prompt the user for the resource to open.
        Object[] files = queryFileResource(filePathPattern);
        if (files != null) {
            for (int i = 0; i < files.length; i++) {
                if (files[i] instanceof IFile) {
                    QueryUtils.openFile((IFile) files[i]);
                }
            }
        }
    }

    /**
     * Query the user for the resources that should be opened
     * 
     * @return the resource that should be opened.
     */
    private static Object[] queryFileResource(String filePathPattern) {

        final IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
        if (window == null) {
            return null;
        }
        final Shell parent = window.getShell();
        final IContainer input = ResourcesPlugin.getWorkspace().getRoot();

        final FilteredResourcesSelectionDialog dialog = new FilteredResourcesSelectionDialog(parent, true, input,
                IResource.FILE);
        dialog.setInitialPattern(filePathPattern);
        dialog.scheduleRefresh();

        final int resultCode = dialog.open();

        if (resultCode != IDialogConstants.OK_ID) {
            return null;
        }

        final Object[] result = dialog.getResult();

        return result;
    }

    /**
     * Open given file in Editor
     * 
     * @param file
     */
    public static void openFile(IFile file) {
        try {

            IWorkbenchWindow activeWorkbenchWindow = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
            if (activeWorkbenchWindow == null) {
                return;
            }
            IWorkbenchPage activePage = activeWorkbenchWindow.getActivePage();
            if (activePage == null) {
                return;
            }
            IDE.openEditor(activePage, file);

        } catch (PartInitException exception) {
            throw new RuntimeException(exception);
        }
    }

    public static String toFilePath(String text) {

        String filePath = text;

        if (text != null && !"".equals(text) && text.indexOf('/') == -1) {

            int lastIndex = text.lastIndexOf('.');
            boolean foundChar = (lastIndex != -1);
            if (foundChar) {
                filePath = text.replace('.', '/');
            }
        }
        return filePath;
    }

    public static String toFileName(String text) {

        final int MAX_FILE_EXT_LEN = 4;

        String fileName = text;

        if (text != null && !"".equals(text) && text.indexOf('/') == -1) {

            int lastIndex = text.lastIndexOf('.');
            boolean foundChar = (lastIndex != -1);
            if (foundChar && ((text.length() - lastIndex) > MAX_FILE_EXT_LEN)) {
                fileName = text.substring(lastIndex + 1);
            }
        }
        return fileName;
    }

    public static String[] getSearchFolderPaths() {
        IPreferenceStore store = FileLinkPlugin.getDefault().getPreferenceStore();
        String folderList = store.getString(PreferenceConstants.PREFERENCE_FOLDERS);

        return getArrayFromString(folderList);
    }

    public static IContainer[] getSearchFolders() {

        String[] foderPaths = getSearchFolderPaths();

        List<IResource> containers = new ArrayList<IResource>();

        if (foderPaths != null) {
            for (String folderPath : foderPaths) {
                IPath path = Path.fromPortableString(folderPath);
                IResource resource = ResourcesPlugin.getWorkspace().getRoot().findMember(path);
                if (resource instanceof IContainer) {
                    containers.add(resource);
                }
            }
        }
        return containers.toArray(new IContainer[0]);
    }

    /*
     * Convert a list of tokens into an array using "," as the tokenizer.
     */
    private static String[] getArrayFromString(String list) {
        String separator = ","; //$NON-NLS-1$
        if (list == null || list.trim().equals("")) { //$NON-NLS-1$
            return new String[0];
        }
        List<String> result = new ArrayList<String>();
        for (StringTokenizer tokens = new StringTokenizer(list, separator); tokens.hasMoreTokens();) {
            String token = tokens.nextToken().trim();
            if (!token.equals("")) { //$NON-NLS-1$
                result.add(token);
            }
        }
        return result.toArray(new String[result.size()]);
    }
}
